package controlador;

import vista.InterfazGraficaVenta;
import vista.Mensaje;
import vista.VentanaIndependiente;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
import java.awt.event.ActionListener;
import java.util.Calendar;
import java.util.Vector;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableModel;

import modelo.Buscador;
import modelo.ClienteDao;
import modelo.Producto;
import modelo.ProductoDao;
import modelo.Venta;
import modelo.VentaDao;
import modelo.VentaDetalle;

public class ControladorVenta implements WindowListener,ActionListener,KeyListener,Buscador
{
    private InterfazGraficaVenta interfazGrafica;
	private ControladorPrincipal controladorPrincipal;
	private TableModel modeloTabla;
	private boolean buscandoCliente;
	
	public ControladorVenta(ControladorPrincipal controladorPrincipal)
	{
		this.controladorPrincipal= controladorPrincipal;
		
		buscandoCliente= false;
		
		modeloTabla= new DefaultTableModel();    
		
		interfazGrafica= new InterfazGraficaVenta();
		
		interfazGrafica.addListener((WindowListener) this);
		interfazGrafica.addListener((ActionListener) this);
		interfazGrafica.addListener((KeyListener) this);
		interfazGrafica.visualizarVentana();
	}
	
	public void iniciar() throws Exception
	{
		Object[] encabezados= {"Codigo","Nombre Corto","Precio Unitario","Cantidad"};
		modeloTabla= new ModeloTabla(encabezados,0);
		interfazGrafica.asignarDatosTabla(modeloTabla);
		
		interfazGrafica.setFecha(String.format("%1$td/%1$tm/%1$tY",java.util.Calendar.getInstance()));
		
		interfazGrafica.setNroFactura(new VentaDao().getNroVentas() + 1);
		interfazGrafica.setPorcDescuento(0.0f);
		interfazGrafica.setPorcImpuesto(0.0f);
		interfazGrafica.asignarCliente("");
		interfazGrafica.setTotal(0.0);
	}
	
	
	private void registrarVenta()
	{
	  try
	  {	
		  Venta venta= new Venta();
		  VentaDao ventaDao= new VentaDao();
		  
		  venta.setCodigoVenta(interfazGrafica.getNroFactura());
		  venta.setFecha(Calendar.getInstance());
		  venta.setCliente(new ClienteDao().getCliente(interfazGrafica.getCliente()));
		  venta.setPorcDescuento(interfazGrafica.getPorcDescuento());
		  venta.setPorcImpuesto(interfazGrafica.getPorcImpuesto());
		  
		  
		  boolean valido= true;
		  
		  if (modeloTabla instanceof ModeloTabla)
		  {
			  for (int i=0; i < modeloTabla.getRowCount(); ++i)
			  {
		         Producto producto= new ProductoDao().obtenerProducto((String) modeloTabla.getValueAt(i, 0));
		         int  cantidad= (Integer) modeloTabla.getValueAt(i, 3);
		         
		         if (ventaDao.cantidadProductosFacturables(producto) < cantidad)
		         { 	 
		         	 valido= false;
		         	 break;
		         }
		         else
		         {
		             venta.agregarVentaDetalle(new VentaDetalle(producto,cantidad)); 
		             
		         } 	 
		         
			  }  
		  }
		  
		  if (venta.validar() && valido)
		  {
			  if (Mensaje.mostrarConfirmacion("Desea Registrar esta Venta?"))
			  {
				  if (ventaDao.registrarVenta(venta))
				  {
					  Mensaje.mostrarInformacion("La Venta se ha realizado con Exito");
				  }
				  else
				  {
					 Mensaje.mostrarError("Error Registrando la Venta");
					 
				  }	
				  iniciar();
					 
			  }	  
		  }
		  else
		  {
			  Mensaje.mostrarError("La Venta no Puede ser Procesada");
			  iniciar();
		  }
	  }
	  catch(Exception e)
	  {
		  Mensaje.mostrarError("Error Registrando la venta");
		  try
		  {
			  iniciar();
		  }
		  catch(Exception excep){}
	  }
	}
	
	private boolean agregado(Producto producto)
	{
		boolean bandera= false;
		
		
		try
		{
			 if (modeloTabla instanceof ModeloTabla)
			 {
				for (int i=0; i < modeloTabla.getRowCount(); ++i)
				{
					String codigo= (String) modeloTabla.getValueAt(i, 0);
					if (producto.getCodigo().equals(codigo))
					{		
						bandera= true;
						break;
					}	
				}
			 }
		}
		catch(Exception e)
		{ 
			bandera=true;
		}	 
		
		return bandera;
	}
	
	private void actualizarTotal()
	{
       try
       {			
			if (modeloTabla instanceof ModeloTabla)
			 {
				double total=0.0;
				for (int i=0; i < modeloTabla.getRowCount(); ++i)
				{
					double precioU= Double.parseDouble(modeloTabla.getValueAt(i, 2).toString());
					int cantidad= Integer.parseInt(modeloTabla.getValueAt(i, 3).toString());
					
			        total += precioU * cantidad;
			        
				}
				
				double porcDescuento= interfazGrafica.getPorcDescuento();
		        double porcImpuesto= interfazGrafica.getPorcImpuesto();
		        
		        interfazGrafica.setTotal(Math.floor(total + ((total * porcImpuesto)/100) - ((total * porcDescuento)/100)));
			 }
       }
       catch(Exception e){}
         
	}
	
	public void agregarProducto(String codProducto)
	{
		if (!codProducto.isEmpty())
		{	
			try
			{
			   Producto producto= new ProductoDao().obtenerProducto(codProducto);
			   
			   if (modeloTabla instanceof ModeloTabla)
			   {
				  if (!agregado(producto))
				  {	  
			        Object[] filaNueva= {producto.getCodigo(),producto.getNombreCorto(),producto.getPrecio(),new Integer(1)};
			        ((ModeloTabla) modeloTabla).addRow(filaNueva);
			        actualizarTotal();
				  }
				  else
					 Mensaje.mostrarInformacion("El Producto ya se ha Agregado a esta Venta"); 
			   }
			   
			}
			catch(Exception e)
			{
				Mensaje.mostrarError("Error Agregando Producto");
				modeloTabla= new DefaultTableModel();
			}
		}	
	}
	
	private void remover()
	{
		 if (modeloTabla instanceof ModeloTabla)
		 {
		     ((ModeloTabla) modeloTabla).removeRow();	 
		 }
	}
	
	
	
	
	@Override
	public void actionPerformed(ActionEvent evt) 
	{
		
		if (evt.getActionCommand().equalsIgnoreCase("BuscarCliente"))
		{
			buscandoCliente=true;
			new ControladorBuscarCliente(this);
			buscandoCliente=false;
		}
		else if (evt.getActionCommand().equalsIgnoreCase("AGREGAR"))
		{
			new ControladorBuscarProducto(this);
		}
		else if (evt.getActionCommand().equalsIgnoreCase("ELIMINAR"))
		{
			remover();
		}
		else if (evt.getActionCommand().equalsIgnoreCase("ACEPTAR"))
		{
		   registrarVenta();
		}
		else if (evt.getActionCommand().equalsIgnoreCase("CANCELAR"))
		{
		    
			try
			{
		       iniciar();
			}catch(Exception exc)
			{
				Mensaje.mostrarError("Error Generando Nro de Factura");
				controladorPrincipal.visualizarVentanaPrincipal();
				interfazGrafica.descargarMemoria();
			} 
			
		}
		else if (evt.getActionCommand().equalsIgnoreCase("SALIR"))
		{
			controladorPrincipal.visualizarVentanaPrincipal();
			interfazGrafica.descargarMemoria();
		}	
		
	}
	
	@Override
	public VentanaIndependiente getVentana() {
		return interfazGrafica.getVentana();
	}

	@Override
	public void asignarElementoBuscado(String elemento) 
	{
		if (buscandoCliente)
	      interfazGrafica.asignarCliente(elemento);
		else
		  this.agregarProducto(elemento);	
	}

	@Override
	public void windowActivated(WindowEvent arg0) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void windowClosed(WindowEvent arg0) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void windowClosing(WindowEvent arg0) {
		controladorPrincipal.visualizarVentanaPrincipal();
		interfazGrafica.descargarMemoria();
	}

	@Override
	public void windowDeactivated(WindowEvent arg0) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void windowDeiconified(WindowEvent arg0) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void windowIconified(WindowEvent arg0) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void windowOpened(WindowEvent arg0) {
		try
		{
	       iniciar();
		}catch(Exception e)
		{
			Mensaje.mostrarError("Error Generando Nro de Factura");
			controladorPrincipal.visualizarVentanaPrincipal();
			interfazGrafica.descargarMemoria();
		} 
		
	}

	@Override
	public void keyPressed(KeyEvent arg0) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void keyReleased(KeyEvent arg0) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void keyTyped(KeyEvent evt) {
		if ((char)KeyEvent.VK_BACK_SPACE!= evt.getKeyChar() && !Character.isDigit(evt.getKeyChar()) && '.'!=evt.getKeyChar())
	         evt.setKeyChar(Character.MIN_VALUE);
		
		actualizarTotal();
		
	}
	
	class ModeloTabla extends DefaultTableModel
	{


	    public ModeloTabla(Object[][] data, Object[] columnNames) {
	        super(data, columnNames);
	    }

	    public ModeloTabla(Object[] columnNames, int rowCount) {
	        super(columnNames, rowCount);
	    }
	    
	    @Override
	    public boolean isCellEditable(int row,int col)
	    {
	        if (col==3)
	            return true;
	        else
	        	return false;
	    }

	    
	    public void removeRow()
	    {
	    	int i = interfazGrafica.getFilaSeleccionada();
	    	if (i != -1)
	    	   super.removeRow(i);
	    }

	    public void setValueAt(Object value, int row, int col)
	    {
	    	
	        Vector rowVector = (Vector)dataVector.elementAt(row);
	        
	       
	        if (col==3)
	        {
	        	try
	        	{
	        		if (Integer.parseInt((String)value) > 0)
	        		{		
	        		    rowVector.setElementAt(Integer.parseInt((String)value), col);
	        		    
			            actualizarTotal();
	        		}    
	        		else
	        			rowVector.setElementAt(new Integer(1), col);
	        	}
	        	catch(Exception e){
	        		rowVector.setElementAt(new Integer(1), col);
	        	}
	        }
	        else
	        {
	            rowVector.setElementAt(value, col);
	        }
	        
	        
	        fireTableCellUpdated(row, col);

	     }
	}

}
